const LexerState = {
  inCall: 0,
  inQuoteString: 1,
};

// 前端文件修改后，触发插件热更新钩子 -> 编译/更新文件
// file: "D:/project/vite/vite-use/src/render.js"
async function handleHMRUpdate(file, server) {
  const { moduleGraph, ws } = server;
  //根据文件获取模块 { type: 'js', url: '/src/render.js', importers: Set(1) { type: 'js', url: '/src/main.js' },  }
  const module = moduleGraph.getModuleById(file);
  if (module) {
    const updates = [];
    const boundaries = new Set();
    propagateUpdate(module, boundaries);
    updates.push(
      ...[...boundaries].map(({ boundary, acceptedVia }) => ({
        type: `${boundary.type}-update`, // 'js-update'
        path: boundary.url, // '/src/main.js'
        acceptedPath: acceptedVia.url, //  // '/src/render.js'
      }))
    );
    // 发送更新的消息
    ws.send({
      type: 'update',
      updates,
    });
  }
}

function updateModules(file, modules, { ws }) {}
function propagateUpdate(node, boundaries) {
  if (!node.importers.size) {
    return true;
  }
  for (const importer of node.importers) {
    if (importer.acceptedHmrDeps.has(node)) {
      boundaries.add({
        boundary: importer,
        acceptedVia: node,
      });
      continue;
    }
  }
  return false;
}
function lexAcceptedHmrDeps(code, start, urls) {
  let state = LexerState.inCall;
  let prevState = LexerState.inCall;
  let currentDep = '';
  function addDep(index) {
    urls.add({
      url: currentDep,
      start: index - currentDep.length - 1,
      end: index + 1,
    });
    currentDep = '';
  }
  for (let i = start; i < code.length; i++) {
    const char = code.charAt(i);
    switch (state) {
      case LexerState.inCall:
        if (char === `'` || char === `"`) {
          prevState = state;
          state = LexerState.inQuoteString;
        }
        break;
      case LexerState.inQuoteString:
        if (char === `'` || char === `"`) {
          addDep(i);
          return false;
        } else {
          currentDep += char;
        }
        break;
      default:
        break;
    }
  }
  return false;
}
exports.handleHMRUpdate = handleHMRUpdate;
exports.updateModules = updateModules;
exports.lexAcceptedHmrDeps = lexAcceptedHmrDeps;
